<?php



/**
 * This is the model class for table "blog_tags".
 *
 * The followings are the available columns in table 'blog_tags':
 * @property string  $id
 * @property string  $title
 * @property string  $alias
 * @property integer $frequency
 * @property string  $lang
 */

class Tags extends CActiveRecord {
    /**
     * Returns the static model of the specified AR class.
     *
     * @param string $className active record class name.
     *
     * @return Tags the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return 'blog_tags';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('title', 'required'),
            array('frequency', 'numerical', 'integerOnly' => true),
            array('title, alias', 'length', 'max' => 255),
            array('lang', 'length', 'max' => 1),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, title, alias, frequency, lang', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array();
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id'        => 'ID',
            'title'     => 'Title',
            'alias'     => 'Alias',
            'frequency' => 'Frequency',
            'lang'      => 'Lang',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.
        $criteria = new CDbCriteria;
        $criteria->compare('id', $this->id, true);
        $criteria->compare('title', $this->title, true);
        $criteria->compare('alias', $this->alias, true);
        $criteria->compare('frequency', $this->frequency);
        $criteria->compare('lang', $this->lang, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    /**
     * Suggests a list of existing tags matching the specified keyword.
     *
     * @param string the keyword to be matched
     * @param integer maximum number of tags to be returned
     *
     * @return array list of matching tag names
     */
    public function suggestTags($keyword, $limit = 20)
    {
        $tags = $this->findAll(array(
            'condition' => 'title LIKE :keyword',
            'order'     => 'frequency DESC, title',
            'limit'     => $limit,
            'params'    => array(
                ':keyword' => '%' . strtr($keyword, array('%' => '\%', '_' => '\_', '\\' => '\\\\')) . '%',
            ),
        ));
        $names = array();
        foreach ($tags as $tag)
            $names[] = $tag->title;

        return $names;
    }

    public static function string2array($tags)
    {
        return preg_split('/\s*,\s*/', trim($tags), -1, PREG_SPLIT_NO_EMPTY);
    }

    public static function array2string($tags)
    {
        return implode(', ', $tags);
    }

    public function updateFrequency($oldTags, $newTags)
    {
        $oldTags = self::string2array($oldTags);
        $newTags = self::string2array($newTags);
        $this->addTags(array_values(array_diff($newTags, $oldTags)));
        $this->removeTags(array_values(array_diff($oldTags, $newTags)));
    }

    public function addTags($tags)
    {
        $criteria = new CDbCriteria;
        $criteria->addInCondition('title', $tags);
        $this->updateCounters(array('frequency' => 1), $criteria);

        foreach ($tags as $title) {
            if (!$this->exists('title=:title', array(':title' => $title))) {
                $tag = new Tags;
                $tag->title = $title;
                $tag->alias = Helper::unicode_convert($title);
                $tag->frequency = 1;
                $tag->lang = Yii::app()->language == 'vi' ? 1 : 2;
                $tag->save();
            }
        }
    }

    protected function beforeSave() {
        $this->alias = Helper::unicode_convert($this->title);

        return parent::beforeSave();
    }

    public function removeTags($tags)
    {
        if (empty($tags))
            return;
        $criteria = new CDbCriteria;
        $criteria->addInCondition('title', $tags);
        $this->updateCounters(array('frequency' => -1), $criteria);
        $this->deleteAll('frequency<=0');
    }

    /**
     * Returns tag names and their corresponding weights.
     * Only the tags with the top weights will be returned.
     *
     * @param integer the maximum number of tags that should be returned
     *
     * @return array weights indexed by tag names.
     */
    public function findTagWeights($lang, $limit = 20)
    {
        $language = $lang == 'en' ? 2 : '1';
        $models = $this->findAll(array(
            'condition' => 'lang=:lang',
            'order' => 'frequency DESC',
            'limit' => $limit,
            'params' => array(
                ':lang' => $language
            )
        ));
        $total = 0;
        foreach ($models as $model)
            $total += $model->frequency;
        $tags = array();
        if ($total > 0) {
            foreach ($models as $model)
                $tags[$model->title] = 8 + (int)(16 * $model->frequency / ($total + 10));
            ksort($tags);
        }

        return $tags;
    }
}